#include <jni.h>

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <android/log.h>
#include <linux/mtgpio.h>

#define TAG "hcj.gpio"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__)

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL
Java_com_ty_gpiotest_Gpio_Cmd(JNIEnv* env, jobject obj, jint cmd, jint pin);
#ifdef __cplusplus
}
#endif

static const char *GPIO_DEV = "/dev/mtgpio";

static const int op_map[] = {
    GPIO_IOCQMODE,        /*GET_MODE_STA*/
    GPIO_IOCTMODE0,       /*SET_MODE_0*/
    GPIO_IOCTMODE1,       /*SET_MODE_1*/
    GPIO_IOCTMODE2,       /*SET_MODE_2*/
    GPIO_IOCTMODE3,       /*SET_MODE_3*/

    GPIO_IOCQDIR,         /*GET_DIR_STA*/
    GPIO_IOCSDIRIN,       /*SET_DIR_IN*/
    GPIO_IOCSDIROUT,      /*SET_DIR_OUT*/

    GPIO_IOCQPULLEN,      /*GET_PULLEN_STA*/
    GPIO_IOCSPULLDISABLE, /*SET_PULLEN_DISABLE*/
    GPIO_IOCSPULLENABLE,  /*SET_PULLEN_ENABLE*/

    GPIO_IOCQPULL,        /*GET_PULL_STA*/
    GPIO_IOCSPULLDOWN,    /*SET_PULL_DOWN*/
    GPIO_IOCSPULLUP,      /*SET_PULL_UP*/

    GPIO_IOCQINV,         /*GET_INV_STA*/
    GPIO_IOCSINVENABLE,   /*SET_INV_ENABLE*/
    GPIO_IOCSINVDISABLE,  /*SET_INV_DISABLE*/

    GPIO_IOCQDATAIN,      /*GET_DATA_IN*/
    GPIO_IOCQDATAOUT,     /*GET_DATA_OUT*/
    GPIO_IOCSDATALOW,     /*SET_DATA_LOW*/
    GPIO_IOCSDATAHIGH,    /*SET_DATA_HIGH*/
};

jint Java_com_ty_gpiotest_Gpio_Cmd(JNIEnv* env, jobject obj, jint cmd, jint pin){
	int fd = -1;
	int ret = -1;

	fd = open(GPIO_DEV, O_WRONLY);
	if (fd < 0)  {
		LOGI("error open fd=%d",fd);
		return ret;
	}
	LOGI("open fd=%d,cmd=%d",fd,cmd);
	ret = ioctl(fd,op_map[cmd],pin);

	if (close(fd) != 0) {
		LOGI("close error");
		return ret;
	}
	return ret;
}
